package org.sbbs.tool;

import java.io.File;
import java.util.Map;
import java.util.Properties;

import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2x.GenericExporter;
import org.hibernate.tool.hbm2x.pojo.POJOClass;

/**
 * This class is used to process FreeMarker templates and
 * produce files from them.
 *
 * @author mraible
 */
public abstract class SbbsAbstractExporter extends GenericExporter {

    public SbbsAbstractExporter() {
        init();
    }

    public SbbsAbstractExporter(Configuration cfg, File outputdir) {
        super(cfg, outputdir);
        init();
    }

    public void init() {
        super.setArtifactCollector(new NoXMLFormatArtifactCollector());
    }

    public String getName() {
        return "sbbs";
    }

    public void doStart() {
        String generateCore = getProperties().getProperty("generate-core");
        if (generateCore != null && generateCore.equals("true")) {
            generateCore();
        }

        String generateWeb = getProperties().getProperty("generate-web");
        if (!"true".equals(generateCore) && generateWeb != null && generateWeb.equals("true")) {
            generateWeb();
        }

        if (generateCore == null && generateWeb == null) {
            generateCore();
            generateWeb();
        }
    }

    protected abstract void generateCore();
    protected abstract void generateWeb();

    protected String getDaoFilename(String daoFramework) {
        if (daoFramework.equalsIgnoreCase("ibatis")) {
            return "iBatis";
        } else if (daoFramework.equalsIgnoreCase("jpa")) {
            return "Jpa";
        } else {
            return Character.toUpperCase(daoFramework.charAt(0)) + daoFramework.substring(1);
        }
    }

    protected GenericExporter configureExporter(String template, String pattern) {

        // Add custom template path if specified
        String[] templatePaths;
        if (getProperties().getProperty("templatedirectory") != null) {
            templatePaths = new String[getTemplatePaths().length + 1];
            templatePaths[0] = getProperties().getProperty("templatedirectory");
            if (getTemplatePaths().length > 1) {
                for (int i = 1; i < getTemplatePaths().length; i++) {
                    templatePaths[i] = getTemplatePaths()[i-1];
                }
            }
        } else {
            templatePaths = getTemplatePaths();   
        }

        GenericExporter exporter = new GenericExporter(getConfiguration(), getOutputDirectory()) {
            @Override
            protected void exportPOJO(Map map, POJOClass element) {
                if (element.getShortName().equals(System.getProperty("sbbs.entity"))) {
                    super.exportPOJO(map, element);
                }
            }

            @Override
            protected String resolveFilename(POJOClass element) {
                String filename = super.resolveFilename(element);
                String packageLocation = getPackageNameForFile(element).replace(".", "/");

                String pojoName = System.getProperty("entity");
                if (pojoName == null) {
                    pojoName = System.getProperty("sbbs.entity");
                }

                // A dot in the entity name means the person is specifying the package.
                if (pojoName.contains(".")) {
                    packageLocation = pojoName.substring(0, pojoName.indexOf(".model"));
                    packageLocation = packageLocation.replace(".", "/");
                }

                if (packageLocation.endsWith("model") && packageLocation.indexOf('/') > -1) {
                    packageLocation = packageLocation.substring(0, packageLocation.lastIndexOf('/'));
                }
                filename = filename.replace("{basepkg-name}", packageLocation);
                return filename;
            }
        };
        exporter.setProperties((Properties) getProperties().clone());
        exporter.setTemplatePath(templatePaths);
        exporter.setTemplateName(template);
        exporter.setFilePattern(pattern);
        exporter.setArtifactCollector(getArtifactCollector());
        exporter.getProperties().put("data", new DataHelper());
        exporter.getProperties().put("util", new StringUtils());

        return exporter;
    }
}
